package com.ruoyi.asset.homepage.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ruoyi.asset.cleaning.domain.bo.CleaningWorkStatisticsBo;
import com.ruoyi.asset.cleaning.domain.bo.SweepCleaningStatisticsBo;
import com.ruoyi.asset.cleaning.service.ISweepCleaningService;
import com.ruoyi.asset.extermination.domain.bo.DisinfectionStatisticsBo;
import com.ruoyi.asset.extermination.service.IDisinfectionService;
import com.ruoyi.asset.homepage.domain.bo.AssetOverviewBo;
import com.ruoyi.asset.homepage.domain.bo.vo.AssetManageStatVo;
import com.ruoyi.asset.homepage.domain.bo.vo.AssetStatisticsVo;
import com.ruoyi.asset.homepage.service.IHomePageService;
import com.ruoyi.asset.lamp.domain.bo.LampMaintenanceStatisticsBo;
import com.ruoyi.asset.lamp.domain.bo.LampWorkStatisticsBo;
import com.ruoyi.asset.lamp.service.ILampMaintenanceService;
import com.ruoyi.asset.maintenance.domain.bo.MaintenanceStatisticsBo;
import com.ruoyi.asset.maintenance.service.IIntegratedMaintenanceService;
import com.ruoyi.asset.park.domain.bo.ParkMaintenanceOverviewBo;
import com.ruoyi.asset.park.domain.vo.ParkCommunityCountVo;
import com.ruoyi.asset.park.domain.vo.ParkWorkStatisticsVo;
import com.ruoyi.asset.park.service.IParkMaintenanceService;
import com.ruoyi.asset.recycle.domain.bo.WasteRecycleStatisticsBo;
import com.ruoyi.asset.recycle.domain.vo.RecycleCommunityCountVo;
import com.ruoyi.asset.recycle.service.IWasteRecycleService;
import com.ruoyi.asset.roadgreening.domain.bo.RoadGreeningOverviewBo;
import com.ruoyi.asset.roadgreening.domain.vo.GreeneryCommunityCountVo;
import com.ruoyi.asset.roadgreening.domain.vo.GreeneryWorkStatisticsVo;
import com.ruoyi.asset.roadgreening.service.IRoadGreeningService;
import com.ruoyi.asset.sorting.domain.bo.GarbageSortingOverviewBo;
import com.ruoyi.asset.sorting.domain.vo.SortingWorkStatisticsVo;
import com.ruoyi.asset.sorting.service.IGarbageSortingService;
import com.ruoyi.asset.toilet.domain.bo.ToiletStatisticsBo;
import com.ruoyi.asset.toilet.domain.vo.ToiletWorkStatisticsVo;
import com.ruoyi.asset.toilet.service.IToiletMaintenanceService;
import com.ruoyi.asset.homepage.enums.ServiceTypeEnum;
import com.ruoyi.asset.tool.domain.bo.ToolStatisticsBo;
import com.ruoyi.asset.tool.service.IToolService;
import com.ruoyi.asset.workman.service.IWorkmanService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.erecord.region.service.IRegionService;
import com.ruoyi.standingbook.extermination.service.IExterminationService;
import com.ruoyi.standingbook.maintenance.service.IMaintenanceService;
import com.ruoyi.standingbook.recycle.service.IRecycleService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 资产数据首页
 *
 * @author lq
 * @date 2023-11-29
 */
@RequiredArgsConstructor
@Service
public class HomePageServiceImpl implements IHomePageService {

    private final IRoadGreeningService roadGreeningService;
    private final IParkMaintenanceService parkMaintenanceService;
    private final IGarbageSortingService garbageSortingService;
    private final IWasteRecycleService wasteRecycleService;
    private final IDisinfectionService disinfectionService;
    private final ISweepCleaningService sweepCleaningService;
    private final ILampMaintenanceService lampMaintenanceService;
    private final IIntegratedMaintenanceService integratedMaintenanceService;
    private final IToiletMaintenanceService toiletMaintenanceService;
    private final IRecycleService recycleService;
    private final IExterminationService exterminationService;
    private final IMaintenanceService maintenanceService;
    private final IWorkmanService workmanService;
    private final IToolService toolService;
    private final IRegionService regionService;

	@Override
	public AssetOverviewBo queryAssetOverview() throws Exception {
		final AssetOverviewBo assetOverviewBo = new AssetOverviewBo();

		ExecutorService executor = Executors.newFixedThreadPool(5);

		// 道路绿化任务
		CompletableFuture<RoadGreeningOverviewBo> roadGreeningTask = CompletableFuture.supplyAsync(() -> {
			return roadGreeningService.getRoadGreeningOverview();
		}, executor);

		// 公园管养任务
		CompletableFuture<ParkMaintenanceOverviewBo> parkTask = CompletableFuture.supplyAsync(() -> {
			return parkMaintenanceService.getParkMaintenanceOverview();
		}, executor);

		// 垃圾分类督导任务
		CompletableFuture<GarbageSortingOverviewBo> sortingTask = CompletableFuture.supplyAsync(() -> {
			return garbageSortingService.getGarbageSortingOverview();
		}, executor);

		// 垃圾收运任务
		CompletableFuture<WasteRecycleStatisticsBo> recycleTask = CompletableFuture.supplyAsync(() -> {
			return wasteRecycleService.getRecycleCount();
		}, executor);

		// 路灯管养任务
		CompletableFuture<LampMaintenanceStatisticsBo> lampTask = CompletableFuture.supplyAsync(() -> {
			return lampMaintenanceService.getLampCount();
		}, executor);

		// 清扫保洁任务
		CompletableFuture<SweepCleaningStatisticsBo> cleaningTask = CompletableFuture.supplyAsync(() -> {
			return sweepCleaningService.getCleaningCount();
		}, executor);

		// 市政公厕管养任务
		CompletableFuture<ToiletStatisticsBo> toiletTask = CompletableFuture.supplyAsync(() -> {
			return toiletMaintenanceService.getToiletCount();
		}, executor);

		// 四害消杀任务
		CompletableFuture<DisinfectionStatisticsBo> exterminationTask = CompletableFuture.supplyAsync(() -> {
			return disinfectionService.getDisinfectionCount();
		}, executor);

		// 一体化维护任务
		CompletableFuture<MaintenanceStatisticsBo> maintenanceTask = CompletableFuture.supplyAsync(() -> {
			return integratedMaintenanceService.getMaintenanceCount();
		}, executor);

		executor.shutdown();

		assetOverviewBo.setRoadGreeningOverview(roadGreeningTask.get());
		assetOverviewBo.setParkMaintenanceOverviewBo(parkTask.get());
		assetOverviewBo.setGarbageSortingOverviewBo(sortingTask.get());

		assetOverviewBo.setWasteRecycleStatisticsBo(recycleTask.get());
		assetOverviewBo.setLampMaintenanceStatisticsBo(lampTask.get());
		assetOverviewBo.setSweepCleaningStatisticsBo(cleaningTask.get());
		assetOverviewBo.setToiletStatisticsBo(toiletTask.get());
		assetOverviewBo.setDisinfectionStatisticsBo(exterminationTask.get());
		assetOverviewBo.setMaintenanceStatisticsBo(maintenanceTask.get());

		return assetOverviewBo;
	}

    @Override
    public JSONArray queryStatistics(String date) {
        date = DateUtil.format(DateUtil.date(), "yyyy-MM-dd");
        String yesterday = "2024-03-13";
        AssetStatisticsVo assetStatisticsVo = new AssetStatisticsVo();
        CleaningWorkStatisticsBo cleaningWorkByDate = sweepCleaningService.getCleaningWorkByDate(date);
        if (cleaningWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            cleaningWorkByDate = sweepCleaningService.getCleaningWorkByDate(yesterday);
        }
        assetStatisticsVo.setCleaningPec(cleaningWorkByDate.getPercent());
        Integer barrelageNum = recycleService.getBarrelageByYearToNow();
        assetStatisticsVo.setRecycleNum(barrelageNum);
        Integer exterminationNum = exterminationService.getNumByYearToNow();
        assetStatisticsVo.setExterminationNum(exterminationNum);
        Integer maintenanceNum = maintenanceService.getNumByYearToNow();
        assetStatisticsVo.setMaintenanceNum(maintenanceNum);
        SortingWorkStatisticsVo sortingWorkByDate = garbageSortingService.getSortingWorkByDate(date);
        if (sortingWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            sortingWorkByDate = garbageSortingService.getSortingWorkByDate(yesterday);
        }
        assetStatisticsVo.setSortingPec(sortingWorkByDate.getPercent());
        ToiletWorkStatisticsVo toiletWorkByDate = toiletMaintenanceService.getToiletWorkByDate(date);
        if (toiletWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            toiletWorkByDate = toiletMaintenanceService.getToiletWorkByDate(yesterday);
        }
        assetStatisticsVo.setToiletPec(toiletWorkByDate.getPercent());
        GreeneryWorkStatisticsVo greeneryWorkByDate = roadGreeningService.getGreeneryWorkByDate(date);
        if (greeneryWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            greeneryWorkByDate = roadGreeningService.getGreeneryWorkByDate(yesterday);
        }
        assetStatisticsVo.setGreeneryPec(greeneryWorkByDate.getPercent());
        ParkWorkStatisticsVo parkWorkByDate = parkMaintenanceService.getParkWorkByDate(date);
        if (parkWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            parkWorkByDate = parkMaintenanceService.getParkWorkByDate(yesterday);
        }
        assetStatisticsVo.setParkPec(parkWorkByDate.getPercent());
        LampWorkStatisticsBo lampWorkByDate = lampMaintenanceService.getLampWorkByDate(date);
        if (lampWorkByDate.getPercent().compareTo(BigDecimal.ZERO) == 0) {
            lampWorkByDate = lampMaintenanceService.getLampWorkByDate(yesterday);
        }
        assetStatisticsVo.setLampPec(lampWorkByDate.getPercent());

        JSONArray curArr = new JSONArray();
        JSONObject cleaningObj = new JSONObject();
        cleaningObj.set("serviceType", ServiceTypeEnum.CLEANING.getTypeName());
        cleaningObj.set("percentage",assetStatisticsVo.getCleaningPec());
        curArr.add(cleaningObj);

        JSONObject recycleObj = new JSONObject();
        recycleObj.set("serviceType", ServiceTypeEnum.RECYCLE.getTypeName());
        recycleObj.set("percentage",assetStatisticsVo.getRecycleNum());
        curArr.add(recycleObj);

        JSONObject exterminationObj = new JSONObject();
        exterminationObj.set("serviceType", ServiceTypeEnum.EXTERMINATION.getTypeName());
        exterminationObj.set("percentage",assetStatisticsVo.getExterminationNum());
        curArr.add(exterminationObj);

        JSONObject maintenanceObj = new JSONObject();
        maintenanceObj.set("serviceType", ServiceTypeEnum.MAINTENANCE.getTypeName());
        maintenanceObj.set("percentage",assetStatisticsVo.getMaintenanceNum());
        curArr.add(maintenanceObj);

        JSONObject sortingObj = new JSONObject();
        sortingObj.set("serviceType", ServiceTypeEnum.SORTING.getTypeName());
        sortingObj.set("percentage",assetStatisticsVo.getSortingPec());
        curArr.add(sortingObj);

        JSONObject toiletObj = new JSONObject();
        toiletObj.set("serviceType", ServiceTypeEnum.TOILET.getTypeName());
        toiletObj.set("percentage",assetStatisticsVo.getToiletPec());
        curArr.add(toiletObj);

        JSONObject greeneryObj = new JSONObject();
        greeneryObj.set("serviceType", ServiceTypeEnum.GREENERY.getTypeName());
        greeneryObj.set("percentage",assetStatisticsVo.getGreeneryPec());
        curArr.add(greeneryObj);

        JSONObject parkObj = new JSONObject();
        parkObj.set("serviceType", ServiceTypeEnum.PARK.getTypeName());
        parkObj.set("percentage",assetStatisticsVo.getParkPec());
        curArr.add(parkObj);

        JSONObject lampObj = new JSONObject();
        lampObj.set("serviceType", ServiceTypeEnum.LAMP.getTypeName());
        lampObj.set("percentage",assetStatisticsVo.getLampPec());
        curArr.add(lampObj);
        return curArr;
    }

    @Override
    public JSONObject queryManageStat(String date, String community) {
        AssetManageStatVo assetManageStatVo = new AssetManageStatVo();
        int workmanCount;
        int carCount;
        int toolCount;
        Integer lampCount = lampMaintenanceService.getLampCountByDateAndCommunity(date, community);
        assetManageStatVo.setLampCount(lampCount);

        Integer toiletCount = toiletMaintenanceService.getToiletByDateAndCommunity(date, community);
        assetManageStatVo.setToiletCount(toiletCount);

        GreeneryCommunityCountVo countVo = roadGreeningService.getGreeneryByDateAndCommunity(date, community);
        assetManageStatVo.setTreeCount(countVo.getNumSum());
        assetManageStatVo.setRoadArea(new BigDecimal(countVo.getAreaSum().toString()));

        ParkCommunityCountVo park = parkMaintenanceService.getParkByDateAndAndCommunity(date, community);
        assetManageStatVo.setParkCount(Integer.valueOf(park.getNumSum()));
        assetManageStatVo.setParkArea(new BigDecimal(park.getAreaSum()));

        Double cleaningArea = sweepCleaningService.getCleaningByDateAndCommunity(date, community);
        assetManageStatVo.setCleanArea(new BigDecimal(cleaningArea.toString()));

        RecycleCommunityCountVo recycle = wasteRecycleService.getRecycleByDateAndCommunity(date, community);
        assetManageStatVo.setPointCount(Integer.valueOf(recycle.getRecyclePointSum()));
        assetManageStatVo.setYearOfKg(new BigDecimal(recycle.getWeightSum()));

        Integer sortingCount = garbageSortingService.getSortingByDateAndCommunity(date, community);
        assetManageStatVo.setCollectionPointCount(sortingCount);

        Integer exterminationCount = disinfectionService.getExterminationByDateAndCommunity(date, community);
        assetManageStatVo.setLocationCount(exterminationCount);

        Integer maintenanceCount = integratedMaintenanceService.getMaintenanceByDateAndCommunity(date, community);
        assetManageStatVo.setMaintenanceProjectCount(maintenanceCount);

        workmanCount = workmanService.getWorkmanByDateAndCommunity(date, community);
        ToolStatisticsBo statisticsBo;
        if (StringUtils.isNotEmpty(community)) {
            assetManageStatVo.setCommunity(community);
            String regionId = regionService.getRegionIdByName(community);
            statisticsBo = toolService.getCommunityByServiceTypeAndDate(null, regionId, date);
        } else {
            statisticsBo = toolService.getCommunityByServiceTypeAndDate(null,null,date);
        }
        carCount = statisticsBo.getVehicleCount();
        toolCount = statisticsBo.getToolCount();
        assetManageStatVo.setWorkmanCount(workmanCount);
        assetManageStatVo.setCarCount(carCount);
        assetManageStatVo.setToolCount(toolCount);
        return JSONUtil.parseObj(assetManageStatVo);
    }
}
